home *** CD-ROM | disk | FTP | other *** search
- /*
- ***********************************************************************
- *
- * Implementations of the FlightWindow
- * a live (animated) window that displays the FlightView and tells it to move on
- *
- ***********************************************************************
- */
-
- #include "FlightWindow.h"
- #include <Palettes.h>
- #include "EventHandlers.h"
-
- FlightWindow::FlightWindow(const ElevationMap& image_map, const int wind_id)
- : ScreenWindow(wind_id),
- viewer(image_map),
- proj_parameters(ScreenWindow::q_bounds()), // Order! proj_parameters is used at view_buffer init...
- view_buffer(image_map,viewer,proj_parameters),
- is_flying(FALSE),
- was_QD_optimized(FALSE)
- {}
-
- FlightWindow::FlightWindow(const ElevationMap& image_map, const int wind_id,
- ScreenRect buffer_rect)
- : ScreenWindow(wind_id),
- viewer(image_map),
- proj_parameters(buffer_rect),
- view_buffer(image_map,viewer,proj_parameters),
- is_flying(FALSE),
- was_QD_optimized(FALSE)
- {}
-
- // Post- (but still is a) constructor
- void FlightWindow::init(void)
- {
- setup_color_env(view_buffer);
- view_buffer.project();
- ScreenWindow::init();
- }
-
- // Negotiate color environment for displaying clouds...
- void FlightWindow::setup_color_env(OffScreenBuffer& offscreen_buffer)
- {
- set_private_palette(offscreen_buffer.q_clut());
- was_QD_optimized = offscreen_buffer.optimize_color_worlds(GetGDevice());
- }
-
- // How many marks were made per second
- int StopWatch::marks_per_sec(void) const
- {
- const int time_elapsed = (time_stopped == 0 ? TickCount() : time_stopped)
- - time_started; // in Ticks
- return time_elapsed == 0 ? 0 : (60*mark_counter)/time_elapsed;
- }
-
- // Window functions
-
- void FlightWindow::draw(void) // It is this function that really draws smth
- {
- //view_buffer.draw(q_bounds());
- { // This is a little bit faster method, works only
- // if we blit to the whole window;
- // view_buffer.draw(q_bounds()); works even if
- // we blit to a user-item control within a dialog
- // window
- PixMapHandle pixmap = view_buffer.get_pixmap();
- assert( LockPixels(pixmap) );
- Rect& pixmap_rect = (**pixmap).bounds;
- CopyBits((const BitMap *)*pixmap, &qd.thePort->portBits, &pixmap_rect,
- q_bounds(), /*ditherCopy*/ srcCopy, nil);
- UnlockPixels(pixmap);
- }
- animate();
- }
-
-
- Boolean FlightWindow::handle_mouse_down(const EventRecord& the_event, WindowPtr where_window, short window_part)
- {
- switch(window_part)
- {
- case inContent:
- return track_mouse(the_event.where);
-
- case inZoomOut:
- return EventHandler::put_back_my_event(EventHandler::zoom_requested),
- false;
-
- case inGrow:
- {
- // SetPort(twindow);
- Rect growth_limits = qd.screenBits.bounds;
- growth_limits.left = 64; // minimal allowed window size
- growth_limits.top = 64;
- DrawGrowIcon (where_window);
- const long new_win_dims =
- ::GrowWindow(where_window, the_event.where, &growth_limits);
- if( new_win_dims == 0 ) // resize was canceled: merely redraw the window
- return refresh(), true;
-
- Point topleft = {0,0}; // Current window location
- LocalToGlobal(&topleft); // .. in global coordinates
- EventHandler::put_back_my_event(EventHandler::resize_requested,
- new_win_dims,topleft);
- return false;
- }
-
- default:
- break;
- }
- return ScreenWindow::handle_mouse_down(the_event,where_window,window_part);
- }
-
- Boolean FlightWindow::handle_null_event(const long event_time)
- {
- if( !is_flying )
- start_flight();
- return TRUE;
- }
-
- // Handles key_down & auto_key events
- Boolean FlightWindow::handle_key_down(const EventRecord& the_event)
- {
- //_error("char pressed %ld",the_event.message & charCodeMask);
- stop_flight(); // The user wanted to take an active role
- switch(the_event.message & charCodeMask)
- {
- case 11: // PgUp
- if( the_event.modifiers & optionKey )
- proj_parameters.climb(1);
- else
- proj_parameters.move_horizon(4);
- break;
-
- case 12: // PgDn
- if( the_event.modifiers & optionKey )
- proj_parameters.climb(-1);
- else
- proj_parameters.move_horizon(-4);
- break;
-
- case 30: // Arrow Up
- viewer.move_ver(2);
- break;
-
- case 31: // Arrow Down
- viewer.move_ver(-2);
- break;
-
- case 28: // Arrow Left
- viewer.move_hor(-4);
- break;
-
- case 29: // Arrow Right
- viewer.move_hor(4);
- break;
-
- case 'z':
- proj_parameters.zoom(-1);
- break;
-
- case 'Z':
- proj_parameters.zoom(1);
- break;
-
- case 'D':
- view_buffer.dump();
- message("\n\nAnimation speed %d frames/sec\n",frame_counter.marks_per_sec());
- message("\nQuickDraw drawing %s optimized\n",
- was_QD_optimized ? "WAS" : "was NOT");
- return FALSE;
-
- default: // Get the parent to handle the other keys:
- return ScreenWindow::handle_key_down(the_event); // he'll probably kill the application
- }
- view_buffer.project();
- refresh();
- return TRUE;
- }
-
- // Track the mouse clicked in content
- // and move the plane as the mouse (still down) moves
- Boolean FlightWindow::track_mouse(Point mouse_down_pt)
- {
- Point prev_point = mouse_down_pt; // In _global_ coordinates!
- stop_flight();
-
- EventRecord new_event;
- while( !OSEventAvail(mUpMask,&new_event) )
- {
- const int delta_x = prev_point.h - new_event.where.h;
- const int delta_y = prev_point.v - new_event.where.v;
- prev_point = new_event.where;
-
- if( abs(delta_x) < 2 && abs(delta_y) < 2 )
- continue; // Ignore mouse dribble....
-
- viewer.move_ver(delta_y);
- viewer.move_hor(delta_x);
- view_buffer.project();
- refresh();
- draw_immediately();
- }
- return TRUE;
- }
-
- // Dealing with viewer position (and animating it)
- FlightWindow::ViewerAnim::ViewerAnim(const ScreenRect& rect)
- : ViewerPosition(rect.q_width()/2,0,0,g_unit),
- sup_xe(rect.q_width()),
- sup_ye(rect.q_height())
- {
- }
-
- // move things a little
- void FlightWindow::ViewerAnim::stir(void)
- {
- move_hor(4);
- move_ver(4);
- }
-
- // Commencing and terminating the flight
- void FlightWindow::start_flight(void)
- {
- is_flying = TRUE;
- refresh();
- frame_counter.start();
- }
-
- void FlightWindow::stop_flight(void)
- {
- is_flying = FALSE;
- frame_counter.stop();
- }
-
- // Move things a little
- // (usually called within draw())
- void FlightWindow::animate(void)
- {
- if( !is_flying )
- return;
- viewer.stir();
- view_buffer.project();
- refresh(); // That would make sure that the next call
- // to WaitNextEvent would get another update
- ++frame_counter;
- }
-
-
- FullFlightWindow::FullFlightWindow(const ElevationMap& image_map, const int wind_id)
- : FlightWindow(image_map,wind_id,qd.screenBits.bounds),
- normal_menu_bar_height(LMGetMBarHeight())
- {
- WindowPtr whole_screen_win = our_window();
- assert( whole_screen_win != nil );
- MoveWindow( whole_screen_win, qd.screenBits.bounds.left, qd.screenBits.bounds.top, true );
- SizeWindow( whole_screen_win, qd.screenBits.bounds.right - qd.screenBits.bounds.left,
- qd.screenBits.bounds.bottom - qd.screenBits.bounds.top, false );
- /****************************************************/
- /* Set the window's visRgn to include the menu bar. */
- /****************************************************/
-
- RectRgn( (*whole_screen_win).visRgn, &qd.screenBits.bounds );
- InvalRect( &qd.screenBits.bounds );
-
- /*************************************************/
- /* Set the global MBarHeight to 0 to prevent any */
- /* other apps from writing to the menu bar. */
- /*************************************************/
- LMSetMBarHeight(0);
- ObscureCursor(); // hide the cursor, use ShieldCursor()???
- }
-
- // Make sure we restore the original Menu Bar height
- // And the gDevice colors we must've screwed up...
- void FullFlightWindow::destroy_it(void)
- {
- LMSetMBarHeight(normal_menu_bar_height); // Restore the normal menu bar height
- RestoreDeviceClut(GetGDevice());
- FlightWindow::destroy_it(); // Continue destructing...
- }
-
- void FullFlightWindow::setup_color_env(OffScreenBuffer& offscreen_buffer)
- {
- was_QD_optimized = offscreen_buffer.impose_on_gdevice(GetGDevice());
- }
-
-
- void FullFlightWindow::draw(void) // It is this function that really draws smth
- {
- //view_buffer.draw(q_bounds());
- { // This is a little bit faster method, works only
- // if we blit to the whole window;
- // view_buffer.draw(q_bounds()); works even if
- // we blit to a user-item control within a dialog
- // window
- PixMapHandle pixmap = get_pixmap();
- assert( LockPixels(pixmap) );
- //GDHandle gd_device = GetGDevice(); // maybe current device?
- //CTabHandle old_ctab = (**pixmap).pmTable;
- //(**pixmap).pmTable = (**(**gd_device).gdPMap).pmTable;
- Rect& pixmap_rect = (**pixmap).bounds;
- //ScreenRect(pixmap_rect).print("pixmap");
- //q_bounds().print("bounds");
- //ScreenRect((**(**gd_device).gdPMap).bounds).print("gd device's rect");
- //_error("done");
- //EraseRect(q_bounds());
- //CopyBits((const BitMap *)*pixmap, (BitMap*)(*(**gd_device).gdPMap), &pixmap_rect,
- // &(**(**gd_device).gdPMap).bounds, /*ditherCopy*/ srcCopy, nil);
- // Make sure that rectangles are appropriate!! that same as gdevice's!!!
- CopyBits((const BitMap *)*pixmap, &qd.thePort->portBits, &pixmap_rect,
- q_bounds(), /*ditherCopy*/ srcCopy, nil);
- //(**pixmap).pmTable = old_ctab;
- UnlockPixels(pixmap);
- }
- animate();
- }
-